home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
disk & file tools
/
hdenv
/
hdenv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
10KB
|
337 lines
/****************************************************************************\
HDEnv 1.3 (3.10.95)
Copyright (C) 1995 by Michael Fedrowitz <mfedrowi@ix.urz.uni-heidelberg.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\****************************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <strings.h>
#include <dos.h>
#ifndef V39
void * __asm AsmCreatePool(register __d0 ULONG,register __d1 ULONG,register __d2 ULONG,register __a6 struct ExecBase *);
void __asm AsmDeletePool(register __a0 void *,register __a6 struct ExecBase *);
void * __asm AsmAllocPooled(register __a0 void *,register __d0 ULONG,register __a6 struct ExecBase *);
void __asm AsmFreePooled(register __a0 void *,register __a1 void *,register __d0 ULONG,register __a6 struct ExecBase *);
#define CreatePool(memFlags,puddleSize,threshSize) AsmCreatePool(memFlags,puddleSize,threshSize,SysBase)
#define DeletePool(poolHeader) AsmDeletePool(poolHeader,SysBase)
#define AllocPooled(poolHeader,memSize) AsmAllocPooled(poolHeader,memSize,SysBase)
#define FreePooled(poolHeader,memory,memSize) AsmFreePooled(poolHeader,memory,memSize,SysBase)
#endif
#define VERSIONTAG "$VER: HDEnv 1.3 " __AMIGADATE__
#define ERR_BREAK 10001
#define COPYBUF 2048
struct File {
struct File *next,*prev;
struct FileInfoBlock fib;
char path[1];
};
struct Dir {
struct File *first,*last;
};
struct HDEnv {
void *pool;
struct Dir env,envarc;
char path[256];
char copybuf[COPYBUF];
long test,verbose;
};
#ifdef V39
const long __oslibversion = 39;
#else
const long __oslibversion = 37;
#endif
const char *versiontag = VERSIONTAG;
struct HDEnv *hde;
long error_code = 0;
void __regargs _CXBRK(void) {
error_code = ERR_BREAK;
}
void free_all(struct HDEnv *hde) {
DeletePool(hde->pool);
FreeMem(hde,sizeof(struct HDEnv));
}
struct HDEnv *alloc_all(void) {
struct HDEnv *hde;
if(hde = AllocMem(sizeof(struct HDEnv),MEMF_CLEAR)) {
if(!(hde->pool = CreatePool(MEMF_CLEAR,10000,10000))) {
error_code = ERROR_NO_FREE_STORE;
free_all(hde);
}
}
else error_code = ERROR_NO_FREE_STORE;
return error_code ? NULL : hde;
}
void add_file(struct Dir *dir,char *path,struct FileInfoBlock *fib) {
struct File *file;
if(file = AllocPooled(hde->pool,sizeof(struct File)+strlen(path))) {
memcpy(&file->fib,fib,sizeof(struct FileInfoBlock));
strcpy(file->path,path);
if(dir->first) {
dir->last->next = file;
file->prev = dir->last;
}
else dir->first = file;
dir->last = file;
}
else error_code = ERROR_NO_FREE_STORE;
}
void scan_dir(struct Dir *dir,char *name) {
BOOL rc;
BPTR l;
long err;
char *path;
struct FileInfoBlock *fib;
if(fib = AllocDosObject(DOS_FIB,NULL)) {
if(path = AllocPooled(hde->pool,256)) {
if(l = Lock(name,ACCESS_READ)) {
rc = Examine(l,fib);
if(rc) rc = ExNext(l,fib);
while(rc) {
strmfp(path,name,fib->fib_FileName);
add_file(dir,path,fib);
if(fib->fib_DirEntryType > 0) scan_dir(dir,path);
chkabort();
if(error_code) break;
rc = ExNext(l,fib);
}
if(!error_code) {
err = IoErr();
if(err != ERROR_NO_MORE_ENTRIES) error_code = err;
}
UnLock(l);
}
FreePooled(hde->pool,path,256);
}
else error_code = ERROR_NO_FREE_STORE;
FreeDosObject(DOS_FIB,fib);
}
else error_code = ERROR_NO_FREE_STORE;
}
struct File *find_file(struct Dir *dir,char *name) {
struct File *file;
BOOL found = FALSE;
file = dir->first;
while(file) {
if(!(strcmp(file->path,name))) {
found = TRUE;
break;
}
file = file->next;
}
return found ? file : NULL;
}
void del_files(void) {
struct File *file;
file = hde->env.last;
while(file) {
if(!(find_file(&hde->envarc,file->path))) {
strmfp(hde->path,"ENV:",file->path);
if(hde->test) Printf("%s\n",hde->path);
else {
if(hde->verbose) Printf("deleting %s...\n",hde->path);
if(!(DeleteFile(hde->path))) error_code = IoErr();
}
}
chkabort();
if(error_code) break;
file = file->prev;
}
}
void copy_files(void) {
struct File *file,*dest;
BOOL copy;
BPTR l,src_fh,dest_fh;
long size,allocsize,bufsize;
void *buf;
file = hde->envarc.first;
while(file) {
copy = FALSE;
strmfp(hde->path,"ENV:",file->path);
if(!(dest = find_file(&hde->env,file->path))) {
if(file->fib.fib_DirEntryType > 0) {
if(hde->test) Printf("%s (created)\n",hde->path);
else {
if(hde->verbose) Printf("creating %s...\n",hde->path);
if(!(l = CreateDir(hde->path))) {
error_code = IoErr();
break;
}
else UnLock(l);
}
}
else copy = TRUE;
}
else if(file->fib.fib_DirEntryType < 0) {
if(CompareDates(&file->fib.fib_Date,&dest->fib.fib_Date)) copy = TRUE;
}
if(copy) {
if(hde->test) Printf("ENVARC:%s to %s\n",file->path,hde->path);
else {
if(hde->verbose) Printf("copying ENVARC:%s to %s...\n",file->path,hde->path);
if(src_fh = Open(file->path,MODE_OLDFILE)) {
if(dest_fh = Open(hde->path,MODE_NEWFILE)) {
buf = NULL;
size = file->fib.fib_Size;
if(size > COPYBUF) {
if(buf = AllocPooled(hde->pool,size)) {
allocsize = size;
bufsize = size;
}
}
if(!buf) {
buf = hde->copybuf;
bufsize = COPYBUF;
allocsize = 0;
}
while(size > 0) {
if(size < bufsize) bufsize = size;
if(Read(src_fh,buf,bufsize) == bufsize) Write(dest_fh,buf,bufsize);
else {
error_code = IoErr();
break;
}
if(size < bufsize) bufsize = size;
size -= bufsize;
}
if(allocsize) FreePooled(hde->pool,buf,allocsize);
Close(dest_fh);
if(error_code) DeleteFile(hde->path);
else {
SetFileDate(hde->path,&file->fib.fib_Date);
SetProtection(hde->path,file->fib.fib_Protection);
SetComment(hde->path,file->fib.fib_Comment);
}
}
else error_code = IoErr();
Close(src_fh);
}
else error_code = IoErr();
}
}
chkabort();
if(error_code) break;
file = file->next;
}
}
int main(void) {
struct RDArgs *rda;
long arg[2] = { 0,0 };
BPTR env,envarc,old;
if(hde = alloc_all()) {
if(rda = ReadArgs("TEST/S,VERBOSE/S",arg,NULL)) {
hde->test = arg[0];
hde->verbose = arg[1];
FreeArgs(rda);
if(env = Lock("ENV:",ACCESS_READ)) {
if(envarc = Lock("ENVARC:",ACCESS_READ)) {
old = CurrentDir(env);
scan_dir(&hde->env,"");
CurrentDir(envarc);
scan_dir(&hde->envarc,"");
if(!error_code) {
if(hde->test) Printf("Would have deleted:\n");
del_files();
if(!error_code) {
if(hde->test) Printf("Would have copied:\n");
copy_files();
}
}
CurrentDir(old);
UnLock(envarc);
}
else error_code = IoErr();
UnLock(env);
}
else error_code = IoErr();
}
else error_code = IoErr();
free_all(hde);
}
if(error_code) {
if(error_code != ERR_BREAK) {
PrintFault(error_code,"HDEnv");
return RETURN_FAIL;
}
else PutStr("*** Break\n");
}
return RETURN_OK;
}